浅谈pytorch中提供的loss函数 您所在的位置:网站首页 pytorch 多输出 loss 浅谈pytorch中提供的loss函数

浅谈pytorch中提供的loss函数

2023-03-16 09:18| 来源: 网络整理| 查看: 265

最近在学习pytorch中提供的18种loss函数,记录下方便查阅

nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')

公式: CE=\sum_{j}y[j]log(p[j])=\sum_{j}y[j]log(\frac{e^{x[j]}}{\sum_{j}e^{x[j]}})\\ y[j]=\begin{cases} 0, j \neq class \\ 1,j=class \end{cases} \\ \text{loss}(x, class) = weight[class] \left(-x[class] + \log\left(\sum_j \exp(x[j])\right)\right)

注意:标量标签为类别索引,模型输出值不要进行softmax操作。

nn.NLLLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')

公式: \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = - w_{y_n} x_{n,y_n}, \quad w_{c} = \text{weight}[c] \cdot \mathbb{1}\{c \not= \text{ignore_index}\}

模型利用log-softmax得到对数似然函数值 x_{n,y_{n}} ,其中 y_n 表示当前样本的类别索引,从而得到该类别模型的输出对数似然函数值,通过直接最小化负数对然函数达到优化目标。相比于nn.CrossEntropyLoss,需要对输出进行log-softmax操作。

nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')

公式: \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = - w_n \left[ y_n \cdot \log x_n + (1 - y_n) \cdot \log (1 - x_n) \right]

上式为经典的二元分类损失函数,需要注意的是模型输出经过了sigmoid函数,即x_n在 [0,1] 之间表示属于1的概率,而标签 y_n 取值为0或1。

nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction='mean', pos_weight=None)

公式: \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = - w_n \left[ y_n \cdot \log \sigma(x_n) + (1 - y_n) \cdot \log (1 - \sigma(x_n)) \right]

观察上式,相比于nn.BCELoss,只是多了对模型输出 x_n 进行sigmoid操作,因此模型输出不再需要经过sigmoid函数。

nn.L1Loss(size_average=None, reduce=None, reduction='mean')

公式: \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = \left| x_n - y_n \right| ,逐元素求差的绝对值

主要用于计算回归预测中预测值与标签值的差异。

nn.MSELoss(size_average=None, reduce=None, reduction='mean'),

公式: \ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = \left( x_n - y_n \right)^2, 逐元素求差的平方

主要用于计算回归预测中预测值与标签值的差异。相比于L1Loss,MSELoss中损失值随着差异成倍增长,而L1Loss为线性增长,意味着模型对于离群点更加敏感。

nn.SmoothL1Loss(size_average=None, reduce=None, reduction='mean'),

公式: z_{i} = \begin{cases} 0.5 (x_i - y_i)^2, & \text{if } |x_i - y_i| < 1 \\ |x_i - y_i| - 0.5, & \text{otherwise } \end{cases}

主要用于计算目标检测(如Fast-RCNN)中的位置偏差损失。相比于L1Loss,SmoothL1Loss对于差异在某个范围(比如1)之内的惩罚要更小,表明网络侧重于位置偏差过大的点,这主要是因为在目标检测网络中真实位置标签也可能存在一定的误差,而且评估标准采用的IOU门限一般为0.5,因此在一定范围内可以放宽要求。

另外需要注意的是该公式保证了损失函数梯度的连续性,如果采用以下公式,分段点将会出现梯度不连续情况

公式:z_{i} = \begin{cases} (x_i - y_i)^2, & \text{if } |x_i - y_i| < 1 \\ |x_i - y_i|, & \text{otherwise } \end{cases}

nn.PoissonNLLLoss(log_input=True, full=False, size_average=None, eps=1e-08, reduce=None, reduction='mean')

公式: \text{target} \sim \mathrm{Poisson}(\text{input})=\frac{\lambda^{target}}{target!}e^{-\lambda}\ \ \ \ \ (1)\\ \text{loss}(\text{input}, \text{target}) = \text{input} - \text{target} * \log(\text{input}) + \log(\text{target!}) \ \ \ \ \ (2)

泊松分布只有一个参数就是 \lambda 对应上式1中的input,表明利用网络模型对 \lambda 进行参数估计。参数估计通常采用在给定观测样本下最大化似然函数方法(详见统计信号处理),因此取概率分布的负log函数作为loss来进行最小化,如上式2。其中target表示观测样本标签,input表示网络输出值(标量)用于估计参数 \lambda 。

需要注意的是:在pytorch实现中,由于 \log(\text{target!}) 为常数,将其忽略。此外,参数 \lambda为正数,所以input也为正数,不过有时为了计算方便,也可对input先求log,然后计算loss,此时log_input设置为True

nn.KLDivLoss(size_average=None, reduce=None, reduction='mean')

公式: KL(P,Q)=E_P[P,Q]=\sum_{n=1}^Np_i*(log(p_i)-log(q_i)) = \sum_{n=1}^Nl_n \\ l(x,y) = L = \{ l_1,\dots,l_N \}, \quad l_n = y_n \cdot \left( \log y_n - x_n \right)

用于衡量两个分布之间的距离,其中期望分布为Q,预测分布为P,因此模型输出必须经过softmax。离散分布取值范围 [1,N] , p_i,q_i 分别表示离散分布取值为 i 的概率。注意:计算loss时默认已经取log了

nn.MarginRankingLoss(margin=0.0, size_average=None, reduce=None, reduction='mean')

公式: \text{loss}(x, y) = \max(0, -y * (x1 - x2) + \text{margin}) \\ y=1, x1 - x2 > margin \\ y=-1, x1 - x2 < -margin

直观理解就是,正标签要求 x_1 比 x_2 至少大margin,反之至少小margin。用于衡量两个向量之间的相似度

nn.MultiLabelMarginLoss(size_average=None, reduce=None, reduction='mean')

公式: \text{loss}(x, y) = \sum_{ij}\frac{\max(0, 1 - (x[y[j]] - x[i]))}{\text{x.size}(0)} \\ x \in \left\{0, \; \cdots , \; \text{x.size}(0) - 1\right\},\ y \in \left\{0, \; \cdots , \; \text{y.size}(0) - 1\right\} \\ 0 \leq y[j] \leq \text{x.size}(0)-1,\ i \neq y[j]

用于多元素预测问题中,比如输入图像中具有蓝天,白云,草地三个元素,而没有人物元素。此时模型输出中蓝天,白云,草地元素对应的输出值相比于人物元素对应的输出值至大于1,也就是模型蓝天,白云,草地元素预测值更大。注意,标签维度为N,且各元素为当前具备元素对应索引,不足用-1补充。

nn.MultiMarginLoss(p=1, margin=1.0, weight=None, size_average=None, reduce=None, reduction='mean')

公式: \text{loss}(x, y) = \frac{\sum_i \max(0, \text{margin} - x[y] + x[i]))^p}{\text{x.size}(0)} \\ x \in \left\{0, \; \cdots , \; \text{x.size}(0) - 1\right\},\ i \neq y

用于多分类问题,默认参数下与nn.MultiLabelMarginLoss很相似,不过需要注意的是,此时的标签y为标量,表示当前样本所属类别。该loss直观理解就是所属类别的输出值要比其他输出值高出一定的门限。

nn.SoftMarginLoss(size_average=None, reduce=None, reduction='mean')

公式: \text{loss}(x, y) = \sum_i \frac{\log(1 + \exp(-y[i]*x[i]))}{\text{x.nelement}()}

说白了就是多输出逐元素进行logistic回归,即逐元素实现二分类,是否两种情况下分子公式如下式所示

y=1,\ log(\frac{1+e^x}{e^x})=-log(p(y=1)) \\ y=-1,\ log(1+e^x)=-log(p(y=-1))

从上式可以看出,最小化loss就是最大化对数似然函数。注意 y[i] 取值为-1,1,而非0,1;

nn.MultiLabelSoftMarginLoss(weight=None, size_average=None, reduce=None, reduction='mean')

公式: loss(x, y) = - \frac{1}{C} * \sum_i y[i] * \log((1 + \exp(-x[i]))^{-1}) + (1-y[i]) * \log\left(\frac{\exp(-x[i])}{(1 + \exp(-x[i]))}\right) \\ i \in \left\{0, \; \cdots , \; \text{x.nElement}() - 1\right\},\ y[i] \in \left\{0, \; 1\right\}

nn.SoftMarginLoss的多标签版本,相比于softmax只能预测多类别中的某一类,该函数逐个对各类别进行二分类。如果y[i]改为-1,1,负号移进log函数中,上式可简化为

\text{loss}(x, y) = \frac{1}{C}\sum_ilog(1 + \exp(-y[i]*x[i]))

注意,此时的y[i]取值为0,1

nn.TripletMarginLoss(margin=1.0, p=2.0, eps=1e-06, swap=False, size_average=None, reduce=None, reduction='mean')

公式: L(a, p, n) = \max \{d(a_i, p_i) - d(a_i, n_i) + {\rm margin}, 0\}

用于衡量三个张量之间的距离关系,此时只关心张量间的距离而非张量自身数值,比如word embedding中张量之间的距离表示word之间的相似度。直观理解就是,1,2之间的距离小于1,3之间的距离某个阈值

nn.HingeEmbeddingLoss(margin=1.0, size_average=None, reduce=None, reduction='mean')

公式: l_n = \begin{cases} x_n, & \text{if}\; y_n = 1,\\ \max \{0, \Delta - x_n\}, & \text{if}\; y_n = -1, \end{cases}

计算两个输入的相似性,常用于非线性enbedding和半监督学习。直观理解,标签为正时希望两者差异越小越好,标签为负时希望两者差异大于某一阈值。注意:输入的为两个张量之差的绝对值。

nn.CosineEmbeddingLoss(margin=0.0, size_average=None, reduce=None, reduction='mean')

公式: \text{loss}(x, y) = \begin{cases} 1 - \cos(x_1, x_2), & \text{if } y = 1 \\ \max(0, \cos(x_1, x_2) - \text{margin}), & \text{if } y = -1 \end{cases}

利用 cos 计算两个向量之间相似度时,相似度越高,值越大,与nn.HingeEmbeddingLoss中采用的两者差的绝对值完全相反。注意:cos的输出范围为 [-1,1] ,所以margin不能取超过1,否则将失去意义。

nn.CTCLoss(blank=0, reduction='mean', zero_infinity=False)

用于解决语音识别中的分词问题,内容加多,详细可自行百度。

就写到这吧,出差在外用笔记本码字着实不易,中间还忘保存,当时都想骂街了。。。。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有